#pragma once

#include "Common.h"
#include "ThreadCache.h"
#include "PageCache.h"
#include "FixedLengthpool.h"

static void* ConcurrentAlloc(size_t size)
{
	assert(size);

	size_t AlignNum = ClassSize::RoundUp(size);
	size_t kpage = AlignNum >> PAGE_SHIFT;

	if (AlignNum > MAX_BYTES) // 33 + KB
	{
		std::lock_guard<std::mutex> lk(PageCache::GetInstance()->_page_mtx); // 这里需要修改page，需要加锁
		Span* span = PageCache::GetInstance()->GetSpan(kpage);

		return (void*)(span->_pageid << PAGE_SHIFT);
	}
	else // 1 ~ 32
	{
		if (!pTLSThreadCache)
		{
			static kele::blockectPool<ThreadCache> ThreadCacheBlockPool;
			std::lock_guard<std::mutex> lk(ThreadCacheBlockPool._mtx); // 问题原因，线程安全问题，多个线程同时向定长内存池申请空间
			pTLSThreadCache = ThreadCacheBlockPool.New();
		}
		return pTLSThreadCache->Allocate(size);
	}

}

static void ConcurrentFree(void* ptr)
{
	assert(ptr);
	// 因为这里span只读，不需要加锁 错！ 如果你读的时候其他线程修改了位置关系，可能会有影响  // 现在可以不加锁
	Span* span = PageCache::GetInstance()->MapBlockToSpan(ptr);
	size_t size = span->_blocksize; // size是对齐后的

	if (size > MAX_BYTES) // 33 + KB
	{
		std::lock_guard<std::mutex> lk(PageCache::GetInstance()->_page_mtx); // 锁

		span->_isUse = false;
		span->_usecount = 0;
		PageCache::GetInstance()->ReleaseSpanToPageCache(span); 
	}
	else // 1 ~ 32
	{
		assert(pTLSThreadCache);
		pTLSThreadCache->Deallocate(ptr, size);
	}

}
